package com.cheng.chengliving.commodity.service.impl;

import com.cheng.chengliving.commodity.dao.AttrAttrgroupRelationDao;
import com.cheng.chengliving.commodity.dao.AttrgroupDao;
import com.cheng.chengliving.commodity.dao.CategoryDao;
import com.cheng.chengliving.commodity.entity.AttrAttrgroupRelationEntity;
import com.cheng.chengliving.commodity.entity.AttrgroupEntity;
import com.cheng.chengliving.commodity.entity.CategoryEntity;
import com.cheng.chengliving.commodity.service.CategoryService;
import org.apache.commons.lang.StringUtils;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cheng.common.utils.PageUtils;
import com.cheng.common.utils.Query;

import com.cheng.chengliving.commodity.dao.AttrDao;
import com.cheng.chengliving.commodity.entity.AttrEntity;
import com.cheng.chengliving.commodity.service.AttrService;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;


@Service("attrService")
public class AttrServiceImpl extends ServiceImpl<AttrDao, AttrEntity> implements AttrService {

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                new QueryWrapper<AttrEntity>()
        );

        return new PageUtils(page);
    }

    @Resource
    private AttrAttrgroupRelationDao attrAttrgroupRelationDao;
    /**
     * 实现方法,完成保存商品基本属性的同时,
     * 需要保持该基本属性和属性组的关联关系
     * 因为该方法涉及到对多表的操作,因此需要进行事务控制
     * @param attrEntity
     */
    @Transactional
    @Override
    public void saveAttrAndRelation(AttrEntity attrEntity) {

        //1. 先保存基本数据
        this.save(attrEntity); //这里会有sql语句操作,后面也有对数据库的操作
        //2. 保存该商品基本属性 和属性组的关联关系
        //满足条件是基本属性且属性组id不为null
        //销售属性没有属性组相关信息
        if (attrEntity.getAttrType() == 1 && attrEntity.getAttrGroupId()!=null){
            AttrAttrgroupRelationEntity attrAttrgroupRelationEntity = new AttrAttrgroupRelationEntity();

            attrAttrgroupRelationEntity.setAttrId(attrEntity.getAttrId());
            attrAttrgroupRelationEntity.setAttrGroupId(attrEntity.getAttrGroupId());

            attrAttrgroupRelationDao.insert(attrAttrgroupRelationEntity);
        }
    }

    /**
     * 1.实现根据分类categoryId+查询条件[key]+进行分页检索[基本属性]的方法
     * 2.根据自己的业务逻辑,进行定制
     */
    @Override
    public PageUtils queryBaseAttrPage(Map<String, Object> params, Long categoryId) {

        //1.先创建QueryWrapper
        QueryWrapper<AttrEntity> queryWrapper =
                new QueryWrapper<AttrEntity>().eq("attr_type", 1);
        //2.考虑categoryId
        if (categoryId!=0) {
            queryWrapper.eq("category_id",categoryId);
        }

        //3.考虑查询用户是否携带了关键字 key
        String key = (String) params.get("key");
        if (StringUtils.isNotBlank(key)){
            queryWrapper.and((obj)->{
                //查询条件是针对category_id是相等条件,attr_name是模糊查询
                obj.eq("attr_id",key).or().like("attr_name",key);
            });
        }
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                queryWrapper
        );

        return new PageUtils(page);
    }

    @Override
    public void updateByAttr(AttrEntity attrEntity) {

        //1. 得到符合条件的数据
        QueryWrapper<AttrEntity> queryWrapper =
                new QueryWrapper<AttrEntity>().eq("attr_id", attrEntity.getAttrId());

            this.update(attrEntity,queryWrapper);

            //2.保存修改后的结果
        QueryWrapper<AttrAttrgroupRelationEntity> queryWrapper1 =
                new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_id", attrEntity.getAttrId());
        AttrAttrgroupRelationEntity attrAttrgroupRelationEntity = new AttrAttrgroupRelationEntity();

        attrAttrgroupRelationEntity.setAttrId(attrEntity.getAttrId());
        attrAttrgroupRelationEntity.setAttrGroupId(attrEntity.getAttrGroupId());
        attrAttrgroupRelationDao.update(attrAttrgroupRelationEntity,queryWrapper1);

    }

    @Override
    public void deleteByAttrId(Collection<? extends Serializable> attrIds) {
        this.removeByIds(attrIds);
        //1. 得到符合条件的数据
        QueryWrapper<AttrAttrgroupRelationEntity> queryWrapper =
                new QueryWrapper<AttrAttrgroupRelationEntity>();

            queryWrapper.in("attr_id",attrIds);

        attrAttrgroupRelationDao.delete(queryWrapper);
    }

    /**
     * 1.实现根据分类categoryId+查询条件[key]+进行分页检索[销售属性]的方法
     * 2.根据自己的业务逻辑,进行定制
     */
    @Override
    public PageUtils querySaleAttrPage(Map<String, Object> params, Long categoryId) {

        //1.先创建QueryWrapper
        QueryWrapper<AttrEntity> queryWrapper =
                new QueryWrapper<AttrEntity>().eq("attr_type", 0);
        //2.考虑categoryId
        if (categoryId!=0) {
            queryWrapper.eq("category_id",categoryId);
        }

        //3.考虑查询用户是否携带了关键字 key
        String key = (String) params.get("key");
        if (StringUtils.isNotBlank(key)){
            queryWrapper.and((obj)->{
                //查询条件是针对category_id是相等条件,attr_name是模糊查询
                obj.eq("attr_id",key).or().like("attr_name",key);
            });
        }
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                queryWrapper
        );

        return new PageUtils(page);
    }

    /**
     * 根据属性组id返回该属性组关联的基本属性
     */
    @Resource
    private AttrDao attrDao;
    @Override
    public List<AttrEntity> getRelationAttr(Long attrgroupId) {

        //1. 根据attrgroupId得到基本属性和属性组关联的实体
        QueryWrapper<AttrAttrgroupRelationEntity> entities =
                new QueryWrapper<AttrAttrgroupRelationEntity>().eq("attr_group_id", attrgroupId);
        List<AttrAttrgroupRelationEntity> relationEntities = attrAttrgroupRelationDao.selectList(entities);
        //2. 将relationEntities的attrId收集到集合中流式计算
        List<Long> attrIds = relationEntities.stream().map(item -> {
            return item.getAttrId();
        }).collect(Collectors.toList());

        //3. 根据得到的attrIds获取对应的attrEntities
        if(attrIds == null || attrIds.size() ==0){
            return null;
        }

        //List<AttrEntity> attrEntities = (List<AttrEntity>) this.listByIds(attrIds);

        QueryWrapper<AttrEntity> attrWrapper = new QueryWrapper<>();
        attrWrapper.in("attr_id",attrIds);
        List<AttrEntity> attrEntities = attrDao.selectList(attrWrapper);
        return attrEntities;
    }

    /**
     * 实现批量删除属性组和属性的关联关系
     * @param attrAttrgroupRelationEntities
     */
    @Override
    public void deleteRelation(AttrAttrgroupRelationEntity[] attrAttrgroupRelationEntities) {

        //调用自己定义的批量删除方法
        attrAttrgroupRelationDao.deleteBatchRelation(Arrays.asList(attrAttrgroupRelationEntities));
    }

    /**
     * 获取某个属性组可以关联的基本属性
     * 1. 如果某个基本属性已经和某个属性组中的属性关联了,就不能再关联了;
     * 2. 某个属性组可以关联的基本属性必须是同一个分类的[categoryId]
     */
    //得到可以关联的属性

    @Resource
    private AttrgroupDao attrgroupDao;

    @Override
    public PageUtils getAllowRelationAttr(Map<String, Object> params, Long attrgroupId) {

        // 1.通过接收的属性组id attrgroupId得到对应的categoryId
        AttrgroupEntity attrgroupEntity = attrgroupDao.selectById(attrgroupId);
        Long categoryId = attrgroupEntity.getCategoryId();

        // ---增加业务需求,排除已经关联的基本属性
        //(1) 先得到当前categoryId的所有属性组
        List<AttrgroupEntity> group =
                attrgroupDao.selectList(new QueryWrapper<AttrgroupEntity>().eq("category_id", categoryId));

        //收集到上面的到group的对应的属性组的id
        List<Long> attrGroupIds = group.stream().map((item) -> {
            return item.getId();
        }).collect(Collectors.toList());

        //(2) 再到关联表中检索有哪些基本属性已经和(1)中得到的属性组关联上
        //得到了相关分类对应属性组中与这些属性组关联的关联实体
        List<AttrAttrgroupRelationEntity> relationEntities = attrAttrgroupRelationDao.selectList(
                new QueryWrapper<AttrAttrgroupRelationEntity>().in("attr_group_id", attrGroupIds));
        //收集上面得到的关联实体中的基本属性id
        List<Long> attrIds = relationEntities.stream().map((item) -> {
            return item.getAttrId();
        }).collect(Collectors.toList());

        // 2.通过得到的categoryId获取到对应的基本属性[attr_type=1]
        QueryWrapper<AttrEntity> attrEntityQueryWrapper =
                new QueryWrapper<AttrEntity>().eq("category_id", categoryId).eq("attr_type",1);
        List<AttrEntity> attrEntities = this.list(attrEntityQueryWrapper);

        //(3) 增加一个排除前面已经关联过的基本属性即可
        if (attrIds !=null && attrIds.size()!=0){
            attrEntityQueryWrapper.notIn("attr_id",attrIds);
        }
        // 3.因为还要支持条件查询,所以考虑携带的检索条件
        String key = (String) params.get("key");
        if (StringUtils.isNotBlank(key)){
            //如果key有内容
            attrEntityQueryWrapper.and((obj)->{
                obj.eq("attr_id",key).or().like("attr_name",key);
            });
        }

        //进行分页查询
        IPage<AttrEntity> page = this.page(
                new Query<AttrEntity>().getPage(params),
                attrEntityQueryWrapper
        );

        return new PageUtils(page);
    }


}
